package com.zx.map.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zx.map.service.RemoteIntefaceVisitService;
import com.zx.map.service.model.*;
import com.zx.map.utils.MyBeanUtils;
import com.zx.mobile.MobileCommonHelper;
import com.zx.platform.service.DirectoryService;
import com.zx.platform.utils.DateUtils;
import com.zx.platform.utils.HttpClientCommon;
import com.zx.scp.utils.PropertyUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by IntelliJ IDEA. User: Administrator Date: 14-3-1 Time: 上午11:07 To
 * change this template use File | Settings | File Templates.
 */
@Component("remoteIntefaceVisitService")
public class RemoteIntefaceVisitServiceImpl implements RemoteIntefaceVisitService {
    private static Logger log = Logger.getLogger(RemoteIntefaceVisitServiceImpl.class);
    private final static String DEFAULTCARDKEY = "2200";
    @Autowired
    private DirectoryService directoryService;

    /**
     * 招行单笔出款
     */
    @Override
    public PayCmbResponseModel outComeSingleByCmb(CreditRepayLogModel creditRepayLogModel, CreditRepayInfoModel model) throws DataAccessException {
        try {
            PayCmbModel payCmbModel = this.transformOutcomeByCMB(creditRepayLogModel, model);
            String requestUrl = PropertyUtil.getValue("singleOutcomeByCMBUrl");
            String str= MyBeanUtils.beanToJson(payCmbModel);
            Map map=new HashMap();
            map.put("params",str);
            // 2.请求
            return MobileCommonHelper.httpRequest(PayCmbResponseModel.class, requestUrl,map);
        } catch (Exception e) {
            log.error("单笔出款调用异常",e);
            throw new RuntimeException("单笔出款调用异常");
        }
    }

    /**
     * 单笔出款  通联
     */
    @Override
    public OutcomeResponse outComeSingle(String amt,
                                         SettleCardInfoModel settleCardInfoModel) throws DataAccessException {
        try {
            OutcomeModel outcomeModel = this.transformOutcome(amt,
                    settleCardInfoModel);
            String requestUrl = PropertyUtil.getValue("singleOutcomeForMapUrl");
            String str= MyBeanUtils.beanToJson(outcomeModel);
            Map map=new HashMap();
            map.put("params",str);
            // 2.请求
            return MobileCommonHelper.httpRequest(OutcomeResponse.class,
                    requestUrl,map);
        } catch (Exception e) {
            log.error("单笔出款调用异常",e);
            throw new RuntimeException("单笔出款调用异常");
        }
    }

    /**
     * 单笔出款通过招行银企直连
     */
    @Override
    public OutcomeResponse outComeSingleByCmb(String amt, String orderId,
                                              SettleCardInfoModel settleCardInfoModel) throws DataAccessException {
        try {
            PayCmbModel payCmbModel = this.transformOutcomeByCMB(amt, orderId, settleCardInfoModel);
            String requestUrl = PropertyUtil.getValue("singleOutcomeByCMBUrl");
            String str= MyBeanUtils.beanToJson(payCmbModel);
            Map map=new HashMap();
            map.put("params",str);
            // 2.请求
            PayCmbResponseModel temp = MobileCommonHelper.httpRequest(PayCmbResponseModel.class, requestUrl,map);
            OutcomeResponse returnRepsonse = new OutcomeResponse();
            returnRepsonse.setBatchSn("");
            returnRepsonse.setErrMsg(temp.getErrMsg());
            returnRepsonse.setReturnCode(temp.getReturnCode());
            returnRepsonse.setSettleDay("");
            returnRepsonse.setSettleOrdId(temp.getCmbOrderId());
            return returnRepsonse;
        } catch (Exception e) {
            log.error("单笔出款调用异常",e);
            throw new RuntimeException("单笔出款调用异常");
        }
    }

    /**
     * 模型转换为 招行银企直连需要模型
     *
     * @param amt
     * @param orderId
     * @param settleCardInfoModel
     * @return
     * @throws UnsupportedEncodingException
     */
    private PayCmbModel transformOutcomeByCMB(String amt, String orderId, SettleCardInfoModel settleCardInfoModel)
            throws UnsupportedEncodingException {
        PayCmbModel payCmbModel = new PayCmbModel();
        String bankName = directoryService.getCaptionByKeyAndValue(DEFAULTCARDKEY, settleCardInfoModel.getDepositBank());
        payCmbModel.setBankName(null != bankName ? bankName : "");//银行名称
        payCmbModel.setCardName(null != settleCardInfoModel.getBankUsrname() ? settleCardInfoModel.getBankUsrname(): "");//持卡人姓名
        payCmbModel.setCardNo(settleCardInfoModel.getBankAccount());
        payCmbModel.setOrderId(orderId);
        payCmbModel.setTradeAmt(amt);//打款金额 为出款金额金额 单位元
        return payCmbModel;
    }

    /**
     * 模态转换
     *
     * @param model
     * @param creditRepayLogModel
     * @return
     * @throws UnsupportedEncodingException
     */
    private PayCmbModel transformOutcomeByCMB(CreditRepayLogModel creditRepayLogModel, CreditRepayInfoModel model)
            throws UnsupportedEncodingException {
        PayCmbModel payCmbModel = new PayCmbModel();
        payCmbModel.setBankCity(null != model.getBankCity() ?model.getBankCity(): "");
        String bankName = directoryService.getCaptionByKeyAndValue(DEFAULTCARDKEY, model.getBankCode());
        payCmbModel.setBankName(null != bankName ? bankName : "");//银行名称
        payCmbModel.setBankProvince(null != model.getBankProvince() ? model.getBankProvince() : "");
        payCmbModel.setCardName(null != model.getCardName() ? model.getCardName() : "");//持卡人姓名
        payCmbModel.setCardNo(model.getBankAccount());
        payCmbModel.setOrderId(creditRepayLogModel.getRepayId());
        payCmbModel.setTradeAmt(creditRepayLogModel.getRepayAmt().toString());//打款金额 为还款金额
        return payCmbModel;
    }

    private OutcomeModel transformOutcome(String amt,
                                          SettleCardInfoModel settleCardInfoModel)
            throws UnsupportedEncodingException {
        OutcomeModel outcomeModel = new OutcomeModel();
        outcomeModel.setAccountName(null != settleCardInfoModel
                .getBankUsrname() ?settleCardInfoModel.getBankUsrname() : "");
        outcomeModel.setAccountNo(settleCardInfoModel.getBankAccount());
        outcomeModel.setAccountProp(MobileCommonHelper.ACCOUNTPROP_PRIVATE);// 对私
        // 对公
        outcomeModel.setBankCode(settleCardInfoModel.getDepositBank());
        BigDecimal amount = new BigDecimal(amt).multiply(new BigDecimal("100"));// 传入分
        outcomeModel.setAmount(String.valueOf(amount.intValue()));
        // 省 市 支行
        outcomeModel.setProvince(null != settleCardInfoModel
                .getDepositBankbranch() ?settleCardInfoModel.getDepositBankbranch() : "");
        outcomeModel.setCity(null != settleCardInfoModel.getDepositBankbranch() ?
                        settleCardInfoModel.getDepositBankbranch(): "");
        outcomeModel.setBranchName(null != settleCardInfoModel
                .getDepositBankbranch() ? settleCardInfoModel.getDepositBankbranch(): "");

        return outcomeModel;
    }

    /**
     * 批量出款
     *
     * @param encashLogModelList
     * @return
     * @throws DataAccessException
     */
    public List<EncashLogModel> outComeBatch(
            List<EncashLogModel> encashLogModelList) throws DataAccessException {
        try {
            // 返回的list
            List<EncashLogModel> returnList = new ArrayList();
            // 1. 组装发送的json
            String requestUrl = PropertyUtil.getValue("batchOutcomeForMapUrl");

            BatchOutcomeModel batchOutcomeModel = new BatchOutcomeModel();
            List<OutcomeModel> outcomeList = new ArrayList<OutcomeModel>();
            Map<String, EncashLogModel> outcomeMap = new HashMap<String, EncashLogModel>();
            for (int i = 0; i < encashLogModelList.size(); i++) {
                EncashLogModel temp = encashLogModelList.get(i);
                outcomeMap.put(String.valueOf(i), temp);
                // 由于部分取现申请 经过扣费后 出现负数情况 排除此类批量结算数据
                if (temp.getSettleAmt() >= 0) {
                    OutcomeModel outcomeModel = this.transformOutcome(temp
                            .getSettleAmt().toString(), temp
                            .getSettleCardInfoModel());
                    outcomeModel.setBatchSn(String.valueOf(i));
                    outcomeList.add(outcomeModel);
                } else {
                    temp.setSettleRemark("该笔结算金额太小 不需要结算");
                    temp.setSettleTime(DateUtils.dateToString(new Date(),
                            "yyyyMMddHHmmss"));
                    temp.setSettleStatus(MobileCommonHelper.OUTCOMESTATUS_SUCCESS);
                    temp.setEncashStatus(MobileCommonHelper.OUTCOMESTATUS_SUCCESS);
                }
            }
            batchOutcomeModel.setOutcomeModelList(outcomeList);
            // 发送json出款数据
            String str= MyBeanUtils.beanToJson(batchOutcomeModel);
            // 2.请求
            HttpClientCommon httpClientCommon = new HttpClientCommon();
            BatchOutcomeResponse response = httpClientCommon.getResult(
                    BatchOutcomeResponse.class, requestUrl, "post", str);
            // 3.得到返回数据并处理
            if (response != null) {
                if ("0000".equals(response.getReturnCode())) {
                    List<OutcomeResponse> responseList = response.getList();
                    if (responseList != null) {
                        for (OutcomeResponse o : responseList) {
                            String batchSn = o.getBatchSn();
                            EncashLogModel temp = outcomeMap.get(batchSn);
                            if (temp != null) {
                                temp.setSettleOrdId(o.getSettleOrdId());
                                temp.setSettleTime(o.getSettleDay());
                                temp.setSettleRemark(o.getErrMsg());
                                temp.setSettleTime(DateUtils.dateToString(
                                        new Date(), "yyyyMMddHHmmss"));
                                if ("0000".equals(o.getReturnCode())) {
                                    temp.setSettleStatus(MobileCommonHelper.OUTCOMESTATUS_SUCCESS);
                                    temp.setEncashStatus(MobileCommonHelper.OUTCOMESTATUS_SUCCESS);
                                } else {
                                    temp.setSettleStatus(MobileCommonHelper.OUTCOMESTATUS_FAIL);
                                    temp.setEncashStatus(MobileCommonHelper.OUTCOMESTATUS_FAIL);
                                }
                                returnList.add(temp);
                            }
                        }
                    }

                } else {// 失败
                    for (Map.Entry<String, EncashLogModel> entry : outcomeMap
                            .entrySet()) {
                        EncashLogModel temp = entry.getValue();
                        temp.setSettleStatus(MobileCommonHelper.OUTCOMESTATUS_NORMAL);
                        temp.setSettleOrdId(response.getSettleOrdId());
                        temp.setSettleRemark(response.getErrMsg());
                        temp.setEncashStatus(MobileCommonHelper.OUTCOMESTATUS_NORMAL);
                        temp.setSettleTime(DateUtils.dateToString(new Date(),
                                "yyyyMMddHHmmss"));
                        returnList.add(temp);
                    }
                }
            }

            return returnList;
        } catch (Exception e) {
            log.error("单笔出款调用异常",e);
            throw new RuntimeException("批量出款调用异常");
        }
    }
}
